/***********************************************************************
    filename:   hgeTexture.h
    created:    Mon Feb 9 2009
    author:     Paul D Turner
*************************************************************************/

#ifndef _HgeTexture_h_
#define _HgeTexture_h_

#include "hgeForwardRef.h"
#include "hgeRenderer.h"
#include "hgeTexture.h"
#include "hgeRenderer.h"

//! Texture implementation for the Renderer.
class Texture
{
public:
	enum PixelFormat
	{
		//! Each pixel is 3 bytes. RGB in that order.
		PF_RGB,
		//! Each pixel is 4 bytes. RGBA in that order.
		PF_RGBA
	};

    /*!
    \brief
        set the D3D9 texture that this Texture is based on to the specified
        texture.
    */
    void setTexture(LPDIRECT3DTEXTURE9 tex);

    /*!
    \brief
        Return the internal D3D9 texture used by this Texture object.

    \return
        Pointer to the D3D9 texture interface that this object is using.
    */
    LPDIRECT3DTEXTURE9 getTexture() const;

    /*!
    \brief
        Sets what the texture should consider as the original data size.

    \note
        This also causes the texel scaling values to be updated.
    */
    void setOriginalDataSize(UINT width, UINT height);

    //! auto called via the Renderer prior to Reset on the Direct3DDevice9.
    void preD3DReset();

    //! auto called via the Renderer after Reset on the Direct3DDevice9.
    void postD3DReset();

    // implement abstract members from base class.
    const Size& getSize() const;
    const Size& getOriginalDataSize() const;
    const Vector2& getTexelScaling() const;
    void loadFromFile(const String& filename);
    void loadFromMemory(const void* buffer, const Size& buffer_size,
                        PixelFormat pixel_format);
    void saveToMemory(void* buffer);

protected:
    // Friends (to allow construction and destruction)
    friend Texture& Renderer::createTexture(void);
    friend Texture& Renderer::createTexture(const String&);
    friend Texture& Renderer::createTexture(const Size&);
    friend Texture& Renderer::createTexture(LPDIRECT3DTEXTURE9 tex);
    friend void Renderer::destroyTexture(Texture&);

    //! Basic constructor.
    Texture(Renderer& owner);
    //! Construct texture from an image file.
    Texture(Renderer& owner, const String& filename);
    //! Construct texture with a given size.
    Texture(Renderer& owner, const Size& sz);
    //! Construct texture that wraps an existing D3D9 texture.
    Texture(Renderer& owner, LPDIRECT3DTEXTURE9 tex);
    //! Destructor.
    virtual ~Texture();

    //! clean up the internal texture.
    void cleanupTexture();
    //! updates cached scale value used to map pixels to texture co-ords.
    void updateCachedScaleValues();
    //! set d_size to actual texture size (d_dataSize is used if query fails)
    void updateTextureSize();

    //! Renderer object that created and owns this texture.
    Renderer& d_owner;
    //! The D3D9 texture we're wrapping.
    LPDIRECT3DTEXTURE9 d_texture;
    //! Size of the texture.
    Size d_size;
    //! original pixel of size data loaded into texture
    Size d_dataSize;
    //! cached pixel to texel mapping scale values.
    Vector2 d_texelScaling;
    //! holds info about the texture surface before we released it for reset.
    D3DSURFACE_DESC d_savedSurfaceDesc;
    //! true when d_savedSurfaceDesc is valid and texture can be restored.
    bool d_savedSurfaceDescValid;
};

#endif // end of guard _HgeTexture_h_
